#ifndef MAPLOADER_H
#define MAPLOADER_H

#include "Common.h"
#include "Tileset.h"
#include "Tilemap.h"

#include <vector>

#define TILE_WIDTH 16
#define TILE_HEIGHT 16
#define LAYERS 4
#define PAGE_WIDTH 30
#define PAGE_HEIGHT 17

#define VIEWPORT_WIDTH (TILE_WIDTH*PAGE_WIDTH)
#define VIEWPORT_HEIGHT (TILE_HEIGHT*PAGE_HEIGHT)

#define STARTING_PAGE_X 128
#define STARTING_PAGE_Y 128

#define CAMERA_START_X ((STARTING_PAGE_X*VIEWPORT_WIDTH) + VIEWPORT_WIDTH/2)
#define CAMERA_START_Y ((STARTING_PAGE_Y*VIEWPORT_HEIGHT) + VIEWPORT_HEIGHT/2)

#define PHYSICAL_L0_LAYER 10
#define PHYSICAL_L1_LAYER 20
#define PHYSICAL_L2_LAYER 30
#define PHYSICAL_L3_LAYER 40

namespace GenBen {

class Page : public noncopyable
{
public:
	Page()
		:  x(0), y(0), tile_map(NULL, NULL, 0)
	{
	}

	Page(Graphics* graphics, Tileset** tilesets, uint tileset_count, byte x, byte y)
		:  x(x), y(y), tile_map(graphics, tilesets, tileset_count)
	{
	}

	byte x, y;

	byte collision_map[PAGE_WIDTH][PAGE_HEIGHT];
	Tilemap<LAYERS, PAGE_WIDTH, PAGE_HEIGHT> tile_map;
};

class Map : public noncopyable
{
public:
	Map(Graphics* graphics, string filename);
	virtual ~Map();

	Page* getPage(byte x, byte y);

	void setCamera(const VectorF& camera_pos) { camera = camera_pos; };
	VectorF getCamera() const { return camera; };
	void moveCamera(const VectorF& camera_pos, float time_scale);

	void draw();

private:
	// Returns coordinates of page which contains given point
	void pageFromPoint(const VectorF& point, byte& x, byte &y);
	// Returns rectangle (in world coordinates) of page
	RectF pageRect(byte x, byte y);
	// Draws single page
	void drawPage(byte x, byte y);

	Graphics* graphics;
	
	Page** pages;
	Page* page_map[256][256];
	uint page_count;
	
	Tileset** tilesets;
	uint tileset_count;

	VectorF camera;
	VectorF camera_speed;
};

} // namespace

#endif
